package cn.hpclub.server.controller.admin;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jfinal.aop.Clear;
import com.jfinal.aop.Duang;
import com.jfinal.ext.plugin.shiro.ShiroMethod;

import cn.dreampie.shiro.core.SubjectKit;
import cn.hpclub.server.bean.SystemConfig;
import cn.hpclub.server.constant.Constant;
import cn.hpclub.server.model.Admin;
import cn.hpclub.server.model.MemberOrg;
import cn.hpclub.server.model.Menu;
import cn.hpclub.server.model.Organization;
import cn.hpclub.server.model.SalesPromotion;
import cn.hpclub.server.model.ServiceReservation;
import cn.hpclub.server.model.Token;
import cn.hpclub.server.service.LoginService;
import cn.hpclub.server.service.MenuService;
import cn.hpclub.server.util.Base64Utils;
import cn.hpclub.server.util.DESCrypto;
import cn.hpclub.server.util.RSAUtils;
import cn.hpclub.server.util.SystemConfigUtil;

/**
 * 后台类 - 后台管理、管理员
 * 
 */
public class AdminController extends BaseAdminController<Admin>{
    private static Logger log         = LoggerFactory.getLogger(LoginService.class);
    private MenuService   menuService = Duang.duang(MenuService.class);

    // 登录页面
    @Clear
    public void login() throws Exception{
        SystemConfig systemConfig = SystemConfigUtil.getSystemConfig();
        setAttr("systemConfig", systemConfig);
        setAttr("base", getRequest().getContextPath());
        setAttr("sessionTimeOut", true);

        genRSAKeyPair();

        render("/admin/admin_login.tpl");
    }

    // 登录验证
    @Clear
    public void singIn(){
        String username = getPara("username", "");
        String password = getPara("password", "");
        String captchaToken = getPara("captchaToken");
        boolean rememberMe = getPara("remember", "").equals("on") ? true : false;

        if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){
            renderErrorMessage("用户名或密码错误!");
            return;
        }

        if(!SubjectKit.doCaptcha("captcha", captchaToken.toLowerCase())){
            log.info("captchaToken=" + captchaToken);
            renderErrorMessage("验证码错误!");
            /* Session中删除过期的验证码存根 */
            removeCaptchaInSession();
            return;
        }
        /* Session中删除过期的验证码存根 */
        removeCaptchaInSession();

        Admin admin = Admin.dao.getAdminByUsername(username);
        if(null == admin){
            renderErrorMessage("用户名或密码错误!");
            return;
        }
        String salt = admin.getStr("salt");
        String newPassword = "";
        try{
            /* RSA 解密 */
            String privateKey = this.getSessionAttr(Constant.PRIVATEKEY);
            String pwdByRSA = new String(RSAUtils.decryptByPrivateKey(Base64Utils.decode(password), privateKey));

            newPassword = DESCrypto.encryptPassword(pwdByRSA, salt);
        }
        catch(Exception e){
            e.printStackTrace();
        }

        // 开始验证
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, newPassword);
        token.setRememberMe(rememberMe);

        try{
            subject.login(token);
        }
        catch(UnknownAccountException ue){
            token.clear();
            renderErrorMessage(ue.getMessage());
            return;
        }
        catch(IncorrectCredentialsException ie){
            token.clear();
            SystemConfig systemConfig = getSystemConfig();
            if(systemConfig.getIsLoginFailureLock()){
                /*
                 * int loginFailureLockCount =
                 * getSystemConfig().getLoginFailureLockCount(); int
                 * loginFailureCount = admin.getInt("loginFailureCount") + 1;
                 * if(loginFailureCount >=
                 * systemConfig.getLoginFailureLockCount()){
                 * admin.set("isAccountLocked", true); admin.set("lockedDate",
                 * new Date()); admin.update(); } admin.set("loginFailureCount",
                 * loginFailureCount); updated(admin); if(loginFailureLockCount
                 * - loginFailureCount <= 3){ renderErrorMessage("若连续" +
                 * loginFailureLockCount + "次密码输入错误,您的账号将被锁定,还有" +
                 * (loginFailureLockCount - admin.getInt("loginFailureCount")) +
                 * " 次机会。"); return; } else{ renderErrorMessage("您的用户名或密码错误!");
                 * return; }
                 */
            } else{
                renderErrorMessage("用户名或密码错误!");
                return;
            }
        }
        catch(LockedAccountException le){
            token.clear();
            renderErrorMessage("用户被锁定!");
            return;
        }
        catch(RuntimeException re){
            re.printStackTrace();
            token.clear();
            renderErrorMessage("登录失败");
            return;
        }

        // 登录成功后
        if(ShiroMethod.authenticated()){
            // admin.set("loginDate", new Date());
            // admin.set("loginIp", getRequest().getRemoteAddr());
            // admin.set("loginFailureCount", 0);
            // admin.update();
            redirect("/admin/center");
        } else{
            renderErrorMessage("用户名或密码错误!");
        }
    }

    private void removeCaptchaInSession(){
        SubjectKit.getSession().removeAttribute("captcha");
    }

    // 管理员退出
    public void logout(){
        Subject currentUser = SecurityUtils.getSubject();
        Session session = SecurityUtils.getSubject().getSession();
		if(session != null){
            currentUser.logout();
            this.removeSessionAttr(session.getId().toString());
        }
        redirect("/admin/login");
    }

    // 后台首页
    public void index(){
        setAttr("java_version", System.getProperty("java.version"));
        setAttr("os", System.getProperty("os.name"));
        setAttr("os_arch", System.getProperty("os.arch"));
        setAttr("os_version", System.getProperty("os.version"));
        setAttr("user_dir", System.getProperty("user.dir"));
        setAttr("tmpdir", System.getProperty("java.io.tmpdir"));
        setAttr("ip", getHostIp(getInetAddress()));
        setAttr("host_name", getHostName(getInetAddress()));
        
        setAttr("dayActiveUserCount", getDayActiveUserCount());// 客户端日活跃用户数
        //setAttr("dayActiveStoreCount", getDayActiveStoreCount()); // 日活跃店铺数
        setAttr("cmccOrderCount", getCmccOrderCount()); // 移动业务订单数量
        setAttr("serviceReservationCount", getServiceReservationCount()); // 宽带业务订单数

        setAttr("userCount", getUserCount()); // 总用户数
        setAttr("dayAddUserCount", getDayAddUserCount()); // 日新增用户
        // setAttr("storeCount", getStoreCount()); // 总店铺数
        setAttr("loginUserCount", getLoginUserCount()); // 登录总用户数
        setAttr("versionNo", SystemConfigUtil.getSystemConfig().getSystemVersion()); // 系统版本号

        render("/admin/admin_index.tpl");
    }

    // 客户端日活跃用户数 DAU
    public Long getDayActiveUserCount(){
        return Token.dao.getDayActiveUserCount();
    }

    // 日活跃店铺数
    public Long getDayActiveStoreCount(){
        return Token.dao.getDayActiveStoreCount();
    }

    // 移动业务订单数量
    public Long getCmccOrderCount(){
        return SalesPromotion.dao.getCmccOrderCount();
    }

    // 移动业务订单数量
    public void getTextForCmccOrderCount(){
        Long orderCount = SalesPromotion.dao.getCmccOrderCount();

        renderText(orderCount.toString());
    }

    // 宽带业务订单数
    public Long getServiceReservationCount(){
        return ServiceReservation.dao.getServiceReservationCount();
    }

    // 宽带业务订单数
    public void getTextServiceReservationCount(){
        Long count = ServiceReservation.dao.getServiceReservationCount();

        renderText(count.toString());
    }

    // 总用户数
    public Long getUserCount(){
        return MemberOrg.dao.getUserCount();
    }

    // 日新增用户
    public Long getDayAddUserCount(){
        return MemberOrg.dao.getDayAddUserCount();
    }

    // 获取总店铺数量
    public Long getStoreCount(){
        return Organization.dao.getStoreCount();
    }

    // 获取登录总用户数
    public Long getLoginUserCount(){
        return Token.dao.getLoginUserCount();
    }

    // 后台主页面、动态获取并显示第一个页面
    public void center(){
        // 获取header菜单条目
        List<Menu> topMenu = menuService.getMenuByLevelID(2);
        setAttr("topMenuList", topMenu);
        if(null != topMenu && topMenu.size() > 0){
            Integer topMenuID = topMenu.get(0).getInt("id");
            setAttr("menuList", menuService.getMenuTreeByParentID(topMenuID));
            setAttr("loginUsername", getLoginAdminName());
            render("/admin/admin_center.tpl");
        }
    }

    // 业务管理
    public void business(){
        // 获取header菜单条目
        redirectMenu();
    }

    // 后台用户管理页面
    public void user(){
        redirectMenu();
    }

    // 后台销售管理页面
    public void order(){
        redirectMenu();
    }

    // 后台系统管理页面
    public void system(){
        redirectMenu();
    }

    // 后台报表管理页面
    public void report(){
        redirectMenu();
    }
    
    // 数据统计分析页面
    public void statistics(){
        redirectMenu();
    }

    // 后台商品管理页面
    public void goods(){
        redirectMenu();
    }

    // 后台商家管理页面
    public void trade(){
        redirectMenu();
    }

    private void redirectMenu(){
        int uid = Integer.parseInt(getPara("uid"));
        setAttr("topMenuList", menuService.getMenuByLevelID(2));
        setAttr("menuList", menuService.getMenuTreeByParentID(uid));
        setAttr("loginUsername", getLoginAdminName());
        render("/admin/admin_center.tpl");
    }

    // 后台中间(显示/隐藏菜单)
    public void middle(){
        render("/admin/admin_middle.tpl");
    }

    // 列表
    public void list(){
        findByPage();
        render("/admin/admin_list.tpl");
    }

    // LocalHost
    private InetAddress getInetAddress(){
    	try{
    		return InetAddress.getLocalHost();
    	}catch(UnknownHostException e){
    		e.printStackTrace();
    	}
    	
    	return null;
    }
    
    // Ip Address
    private String getHostIp(InetAddress netAddress){
    	if(null == netAddress){
    		return "";
    	}
    	
    	String ip = netAddress.getHostAddress();
    	
    	return ip;
    }
    
    // Host Name
    private String getHostName(InetAddress netAddress){
    	if(null == netAddress){
    		return "";
    	}
    	
    	String hostName = netAddress.getHostName();
    	
    	return hostName;
    }
}
